#include <stdio.h>
#include <stdlib.h>

// Include OpenCV's C++ Interface
#include "opencv2/opencv.hpp"

// Include the rest of our code!
//#include "detectObject.h"       // Easily detect faces or eyes (using LBP or Haar Cascades).
#include "beauty.h"
#include "ImageUtils.h"      // Shervin's handy OpenCV utility functions.

using namespace cv;
using namespace std;

static double **mat_create1(int rows, int cols)
{
	double **M; int i;

	M = (double**) malloc(rows * sizeof(double*));
	for (i=0; i<rows; i++)
		M[i] = (double*) malloc(cols * sizeof(double));

	return M;
}



static double **mat_read(FILE *fp, int *rows, int *cols)
{
	int i, j; double **M;

	fscanf(fp, "%d %d", rows, cols);
	M = mat_create1(*rows, *cols);

	for (i=0; i<*rows; i++) {
		for (j=0; j<*cols; j++)
			fscanf(fp, "%lf ", &(M[i][j]));	
	}

	return M;	
}



static void mat_print(double **M, int rows, int cols)
{
	int i, j;

	for (i=0; i<rows; i++) {
		for (j=0; j<cols; j++) {
			printf("%0.6f", M[i][j]);
			if (j < cols - 1)
				printf(" ");
		}
		printf("\n");
	}
}




int main(int argc, char *argv[]){


// 	int menu = 0;
// 	scanf("%d", &menu);
// 	if (menu == 0) {
// 		double param1, param2;
// 		scanf("%lf%lf", &param1, &param2);//-0.026 0.036
// 		Mat src = imread("r34_512.jpg");
// 		Mat mask=imread("mask_512.png",CV_LOAD_IMAGE_GRAYSCALE);
// 		Mat red = Mat(cvSize(src.cols, src.rows), CV_8UC3);
// 		Mat dest = Mat(cvSize(src.cols, src.rows), CV_8UC3);
// 		Mat delta = Mat(cvSize(src.cols, src.rows), CV_8UC3);
// 		decompose(src, mask, red, delta, dest, 0, 1, param1, param2);
// 
// 		resize(red,red,Size(512,512),CV_INTER_LINEAR);
// 		resize(delta,delta,Size(512,512),CV_INTER_LINEAR);
// 		resize(dest,dest,Size(512,512),CV_INTER_LINEAR);
// 
// 		imshow("red", red);
// 		imshow("delta", delta);
// 		imshow("dest", dest);
// 
// 		imwrite("h.jpg", red);
// 		imwrite("m.jpg", delta);
// 		imwrite("d.jpg", dest);
// 
// 		cvWaitKey(0);
// 
// 		//decompose(0, 1, 0, 0);
// 		printf("222");
// 		return 1;
// 	}
// 	else if (menu == 1) {
// 		//decompose(1, 0, -0.017, 0.019);
// //		decompose(1, 0, 0, 0);
// 		printf("222");
// 		return 1;
// 	}
// 	else if (menu == 2 ){
// 		Mat input = imread("delta_1.jpg");
// 		cvtColor(input, input, CV_BGR2BGRA);
// 
// 		int a = 1536;
// 
// 		Mat destH = Mat(cvSize(a, a), CV_8UC3);
// 		Mat destL = Mat(cvSize(a, a), CV_8UC3);
// 
// 		delayer(input, destH, DELAYER_HIGH, 15, 0.2);
// 		delayer(input, destL, DELAYER_LOW, 15, 0.2);
// 		imwrite("median_h.jpg", destH);
// 		imwrite("median_l.jpg", destL);
// 
// 		resize(destH,destH,Size(512,512),CV_INTER_LINEAR);
// 		resize(destL,destL,Size(512,512),CV_INTER_LINEAR);
// 		imshow("H", destH);
// 		imshow("L", destL);
// 		cvWaitKey(0);
// 		return 1;
// 	}
// 	else if (menu == 4) {
// 		FILE *fp;
// 		fp = fopen("PCAset.data", "r");
// 		double **X, **K, **W, **A, **S;
// 		int rows, cols, compc;
// 		compc = 2;
// 		X = mat_read(fp, &rows, &cols);
// 		W = mat_create1(compc, compc);
// 		A = mat_create1(compc, compc);
// 		K = mat_create1(cols, compc);
// 		S = mat_create1(rows, cols);	
// 		fastICA(X, rows, cols, compc, K, W, A, S);
// 		mat_print(A, compc, compc);
// 		system("pause");
// 		return 1;
// 	}
// 	argv[1] = "0";
// 	argv[2] = "D:\\project\\graphics\\landmark_pictures\\icme1.jpg";
// 	argv[3] = "D:\\project\\graphics\\landmark_pictures\\icme1_mask.jpg";
// 	argv[4] = "1";
// 	argv[5] = "0";
// 	argv[6] = "0";
// 	argv[7] = "0";
// 	argv[8] = "4";

	if (atof(argv[1]) == 0) {
		/**
		* decomposition
		*/
		printf("start...\n");

		Mat src = imread(argv[2]);
		Mat mask=imread(argv[3],CV_LOAD_IMAGE_GRAYSCALE);
		Mat red = Mat(cvSize(src.cols, src.rows), CV_8UC3);
		Mat dest = Mat(cvSize(src.cols, src.rows), CV_8UC3);
		Mat delta = Mat(cvSize(src.cols, src.rows), CV_8UC3);
		decompose(src, mask, red, delta, dest, atof(argv[4]), atof(argv[5]), atof(argv[6]), atof(argv[7]));

		string picname = string(argv[2]);
		int pos = picname.find('.');
		string name = picname.substr(0, pos);

		string nameH = name + "H.jpg";
		string nameM = name + "M.jpg";
		string nameD = name + "D.jpg";

		imwrite(nameH.data(), red);
		imwrite(nameM.data(), delta);
		imwrite(nameD.data(), dest);

		resize(red, red, Size(512,512),CV_INTER_LINEAR);
		resize(delta, delta, Size(512,512),CV_INTER_LINEAR);
		resize(dest, dest, Size(512,512),CV_INTER_LINEAR);

		imshow("h", red);
		imshow("m", delta);
		imshow("d", dest);

		printf("successfully\n");
		
		cvWaitKey(0);

		return 1;
	}
	else if (atof(argv[1]) == 1) {
		/**
		 * draw mask
		 */
		Mat srcMat = imread(argv[2]);
		Mat mask1 = Mat(cvSize(srcMat.cols, srcMat.rows), CV_8UC4);
		Mat mask2 = Mat(cvSize(srcMat.cols, srcMat.rows), CV_8UC4);
		int landmarkArray[FACEPP_POINT_COUNT*2];
		FILE *fp;
		fp=fopen("./landmarks.txt","r");
		int i = 0;
		while(!feof(fp))
		{
			int x,y;
			fscanf(fp,"%d %d\n",&x,&y);
			landmarkArray[i++] = x;
			landmarkArray[i++] = y;
		}
		createMask(mask1, mask2, landmarkArray, srcMat.cols, srcMat.rows);
		string picname = string(argv[2]);
		int pos = picname.find('.');
		string name = picname.substr(0, pos);
		string name1 = name + "_m.jpg";
		string name2 = name + "_mask.jpg";
		string name3 = name + "_mask2.jpg";
		for (int i=0; i<mask1.rows; i++) {
			for (int j=0; j<mask1.cols; j++) {
 				Vec4b bgr = mask1.at<Vec4b>(i,j);
				if ((bgr.val[0] == 0)&&(bgr.val[1] == 0)&&(bgr.val[2] == 0)) {
					srcMat.at<Vec3b>(i, j).val[0] = 0;
					srcMat.at<Vec3b>(i, j).val[1] = 0;
					srcMat.at<Vec3b>(i, j).val[2] = 0;
				}
			
			}
		}
		//imshow("src", srcMat);
		imwrite(name1.data(), srcMat);
		imwrite(name2.data(), mask1);
		imwrite(name3.data(), mask2);
		//cvWaitKey(0);
		return 1;
	}
	else if (atof(argv[1]) == 3) {
		Mat input = imread(argv[2]);
		Mat dst;
		bilateralFilter( input, dst, atof(argv[3]), atof(argv[3])*2, atof(argv[3])/2);
		imwrite("bi_filter.jpg", dst);

	}
	

// 	const char* imageName = "jcy.jpg";
// 	Mat mat = cv::imread(imageName);
// 	Mat mat2 = Mat(mat.rows, mat.cols, CV_8UC4);
// 	Mat mat3 = Mat(mat.rows, mat.cols, CV_8UC4);
// 	cvtColor(mat, mat2, CV_RGB2RGBA);
// //	openCVGraphic(mat.cols, mat.rows, mat2, mat3, CARTOON_PROCESS, 1);
// // 	imshow("test_in", mat2);
// // 	imshow("test_out", mat3);
// 	Mat mat4 = Mat(512, 512, CV_8UC4);
// 	clock_t t1 = clock();
// 	openCVGraphic(0, 0, mat4, mat4, SKIN_BEAUTY_PROCESS, 0);
// 	clock_t t2 = clock();
// 	std::cout<<"time: "<<t2-t1<<std::endl;
// 	imshow("result", mat4);
// 	cvWaitKey(0);
// 	imwrite("origin.jpg", mat4);
// 	return 1;

// 	Mat mat;
// 	mat = main_process(0.5, -1, IMAGE_H, IMAGE_M, IMAGE_D);
// 	imshow("result", mat);
// 	cvWaitKey(0);
// 	return 	
}

